/*
** Mortem's HGE Addon 1.4
** Copyright (C) 2006-2007, Osokin 'elmortem' Makar
** http://elmortem.mirgames.ru
**
** Widget engine.
*/

#include <hge.h>
#include <mhaengine.h>
#include <stdio.h>
#include <mhalist.h>
#include <mhavista.h>

HGE *mhaWidget::hge = 0;

HGE *mhaEngine::hge = 0;
mhaEngine *mhaEngine::Engine = 0;

mhaEngine::mhaEngine(void) {
#ifndef HGE_STATEMACHINE
	widgets = new mhaList(false);
	RenderModal = 0;
#endif
	inGameTime = 0.f;
}

mhaEngine::~mhaEngine(void) {	
#ifndef HGE_STATEMACHINE
	// delete widgets
	delete widgets;
#endif

	if(hge) {
		hge->System_Log(TXT("  In game time: %0.2d:%0.2d:%0.2d"), (int)inGameTime / 3600, ((int)inGameTime % 3600) / 60, (int)inGameTime % 60);
		hge->System_Shutdown();
		hge->Release();
	}

	Engine = 0;
}

void mhaEngine::Clear(void) {
#ifndef HGE_STATEMACHINE
	// exec OnHide
	widgets->Begin();
	mhaWidget *w = (mhaWidget*)widgets->Next();
	while(w) {
		w->OnHide();
		w->WidgetUpdateModal = false;
		w->WidgetRenderModal = false;
		w = (mhaWidget*)widgets->Next();
	}

	// clear lists
	widgets->Clear();
	RenderModal = 0;
#else
	hge->System_Clear();
#endif
}


void mhaEngine::Show(mhaWidget *widget, bool renderModal) {
#ifndef HGE_STATEMACHINE
	if(!widget) return;
	widget->WidgetUpdateModal = false;
	widget->WidgetRenderModal = renderModal;
	widgets->AddFirst(widget);
	if(renderModal) RenderModal = widget;
	widget->OnActive();
	widget->OnShow();
#else
	hge->System_Show(widget, renderModal);
#endif
}

int mhaEngine::ShowModal(mhaWidget *widget, bool renderModal) {
#ifndef HGE_STATEMACHINE
	if(!widget) return 0;
	widget->WidgetUpdateModal = true;
	widget->WidgetRenderModal = renderModal;
	widgets->AddFirst(widget);
	if(renderModal) RenderModal = widget;
	widget->OnActive();
	widget->OnShow();
	return 0;
#else
	return hge->System_ShowModal(widget, renderModal);
#endif
}

void mhaEngine::Hide(mhaWidget *widget) {
#ifndef HGE_STATEMACHINE
	if(!widget) return;
	widget->OnHide();
	widget->WidgetUpdateModal = false;
	widget->WidgetRenderModal = false;
	if(RenderModal == widget) RenderModal = 0;
	if(widget->WidgetUpdateModal) {
		widgets->SetCurr(widget);
		widgets->Next();
		mhaWidget *w = (mhaWidget*)widgets->Next();
		while(w) {
			w->OnActive();
			if(w->WidgetRenderModal) RenderModal = w;
			if(w->WidgetUpdateModal) break;
			w = (mhaWidget*)widgets->Next();
		}
	}
	widgets->Remove(widget);
#else
	hge->System_Hide(widget);
#endif
}

bool mhaEngine::Start(const HGE_CHAR *path, const HGE_CHAR *title) {
	hge = hgeCreate(HGE_VERSION);
	if(!hge) return false;
	hge->System_SetState(HGE_USERDATA, this);

	mhaGetUserPath(path, SavePath, MAX_PATH-1);

	HGE_CHAR Path[MAX_PATH];
	hge->System_SetState(HGE_SHOWSPLASH, false);
	HGE_SPRINTF(Path, TXT("%sgame.log"), SavePath);
	hge->System_SetState(HGE_LOGFILE, Path);
	HGE_SPRINTF(Path, TXT("%sgame.cfg"), SavePath);
	hge->System_SetState(HGE_INIFILE, Path);
	hge->System_SetState(HGE_FRAMEFUNC, mhaEngine::StaticUpdate);
	hge->System_SetState(HGE_RENDERFUNC, mhaEngine::StaticRender);
	hge->System_SetState(HGE_EXITFUNC, mhaEngine::StaticExit);
	hge->System_SetState(HGE_FOCUSLOSTFUNC, mhaEngine::StaticFocusLost);
	hge->System_SetState(HGE_FOCUSGAINFUNC, mhaEngine::StaticFocusGain);
	hge->System_SetState(HGE_GFXRESTOREFUNC, mhaEngine::StaticGfxRestore);
	hge->System_SetState(HGE_TITLE, title);
	hge->System_SetState(HGE_USESOUND, false);
	hge->System_SetState(HGE_WINDOWED, !(bool)hge->Ini_GetInt(TXT("options"), TXT("fullscreen"), (int)false));
	hge->System_SetState(HGE_SCREENWIDTH, 800);
	hge->System_SetState(HGE_SCREENHEIGHT, 600);
	hge->System_SetState(HGE_SCREENBPP, 32);
	hge->System_SetState(HGE_HIDEMOUSE, true);
	hge->System_SetState(HGE_DONTSUSPEND, false);
	hge->System_SetState(HGE_FPS, 60);
	hge->System_SetState(HGE_TEXTUREFILTER, true);
	hge->System_SetState(HGE_FXVOLUME, hge->Ini_GetInt(TXT("options"), TXT("soundvolume"), 100));
	hge->System_SetState(HGE_MUSVOLUME, hge->Ini_GetInt(TXT("options"), TXT("musicvolume"), 100));

	if(!PreInit()) {
		hge->System_Log(TXT("Error in PreInit() method."));
		return false;
	}

	Width = (float)hge->System_GetState(HGE_SCREENWIDTH);
	Height = (float)hge->System_GetState(HGE_SCREENHEIGHT);
	HalfWidth = Width * 0.5f;
	HalfHeight = Height * 0.5f;

	if(hge->System_Initiate()) {
		hge->System_Log(TXT("MHA Engine ver. %X.%X"), MHA_VERSION >> 8, MHA_VERSION & 0xFF);

		hge->Random_Seed();

		if(!Init()) {
			hge->System_Log(TXT("Error! Engine not init."));
			return false;
		}
			
		hge->System_Start();
	} else {
		hge->System_Log(TXT("Error in System_Initiate() method."));
		return false;
	}

	return true;
}

bool mhaEngine::Update(float delta) {
	inGameTime += delta;
#ifndef HGE_STATEMACHINE
	bool res = false;
	widgets->Begin();
	mhaWidget *w = (mhaWidget*)widgets->Next();
	while(w) {
		res = res || w->Update(delta);
		if(w->WidgetUpdateModal) return res;
		w = (mhaWidget*)widgets->Next();
	}
	return res;
#else
	return false;
#endif
}

bool mhaEngine::Render(void) {
#ifndef HGE_STATEMACHINE
	hge->Gfx_BeginScene();
	_render();
	hge->Gfx_EndScene();
#endif
	return false;
}

bool mhaEngine::FocusLost(void) {
#ifndef HGE_STATEMACHINE
	bool res = false;
	widgets->Begin();
	mhaWidget *w = (mhaWidget*)widgets->Next();
	while(w) {
		res = res || w->FocusLost();
		w = (mhaWidget*)widgets->Next();
	}
	return res;
#else
	return false;
#endif
}

bool mhaEngine::FocusGain(void) {
#ifndef HGE_STATEMACHINE
	bool res = false;
	widgets->Begin();
	mhaWidget *w = (mhaWidget*)widgets->Next();
	while(w) {
		res = res || w->FocusGain();
		w = (mhaWidget*)widgets->Next();
	}
	return res;
#else
	return false;
#endif
}

bool mhaEngine::GfxRestore(void) {
#ifndef HGE_STATEMACHINE
	bool res = false;
	widgets->Begin();
	mhaWidget *w = (mhaWidget*)widgets->Next();
	while(w) {
		res = res || w->GfxRestore();
		w = (mhaWidget*)widgets->Next();
	}
	return res;
#else
	return false;
#endif
}

bool mhaEngine::Exit(void) {
#ifndef HGE_STATEMACHINE
	bool res = false;
	widgets->Begin();
	mhaWidget *w = (mhaWidget*)widgets->Next();
	while(w) {
		res = res || w->Exit();
		w = (mhaWidget*)widgets->Next();
	}
	return res;
#else
	return true;
#endif
}

bool mhaEngine::StaticUpdate(void) {
	if(!Engine) return true;
	return Engine->Update(hge->Timer_GetDelta());
}

bool mhaEngine::StaticRender(void) {
	if(!Engine) return false;
	return Engine->Render();
}

bool mhaEngine::StaticExit(void) {
	if(!Engine) return true;
	return Engine->Exit();
}

bool mhaEngine::StaticFocusLost(void) {
	if(!Engine) return true;
	return Engine->FocusLost();
}

bool mhaEngine::StaticFocusGain(void) {
	if(!Engine) return true;
	return Engine->FocusGain();
}

bool mhaEngine::StaticGfxRestore(void) {
	if(!Engine) return true;
	return Engine->GfxRestore();
}

#ifndef HGE_STATEMACHINE
void mhaEngine::_render(void) {
	widgets->End();
	mhaWidget *widget = (mhaWidget*)widgets->Prev();

	bool rndr = true;
	if(RenderModal) rndr = false;
	while(widget) {
		if(RenderModal && widget == RenderModal) rndr = true;
		if(rndr) widget->Render();

		widget = (mhaWidget*)widgets->Prev();
	}
}
#endif
